"""通用混入类 - 提供配置式的搜索、过滤、排序功能"""

from django.db.models import Q
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend


class ConfigurableActionMixin:
    """
    配置式Action混入类 - 提供类似ViewSet的搜索、过滤、排序配置

    支持的URL参数格式：
    - 搜索: ?search=关键词
    - 过滤: ?字段名=值 或 ?字段名__查询类型=值
    - 排序: ?ordering=字段名 或 ?ordering=-字段名 (降序)
    - 分页: ?page=页码&page_size=每页数量
    """

    def apply_action_filters(self, queryset, request, action_config=None):
        """
        应用配置式的搜索、过滤、排序

        Args:
            queryset: 查询集
            request: 请求对象 (支持Django WSGIRequest和DRF Request)
            action_config: Action配置字典，包含以下键：
                - search_fields: 搜索字段列表
                  示例: ['name', 'email'] -> URL: ?search=关键词

                - filterset_fields: 过滤字段配置，支持多种格式：
                  1. 列表格式: ['field1', 'field2'] -> URL: ?field1=value&field2=value
                  2. 简单字典: {'param': 'field'} -> URL: ?param=value
                  3. ViewSet字典: {'field': ['exact', 'icontains']} -> URL: ?field=value&field__icontains=value

                - ordering_fields: 排序字段列表
                  示例: ['name', 'created_at'] -> URL: ?ordering=name 或 ?ordering=-created_at

                - ordering: 默认排序
                  示例: ['name', '-created_at']

        Returns:
            处理后的查询集
        """
        if not action_config:
            return queryset

        # 1. 应用搜索
        search_fields = action_config.get('search_fields', [])
        if search_fields:
            queryset = self._apply_search(queryset, request, search_fields)

        # 2. 应用过滤 - 支持filterset_fields（ViewSet标准格式）
        filter_fields = action_config.get('filterset_fields', action_config.get('filter_fields', {}))
        if filter_fields:
            queryset = self._apply_filters(queryset, request, filter_fields)

        # 3. 应用排序 - 支持ordering（ViewSet标准格式）
        ordering_fields = action_config.get('ordering_fields', [])
        default_ordering = action_config.get('ordering', action_config.get('default_ordering', []))
        if ordering_fields or default_ordering:
            queryset = self._apply_ordering(queryset, request, ordering_fields, default_ordering)

        return queryset

    def _get_query_params(self, request):
        """获取查询参数 - 兼容Django和DRF的Request对象"""
        if hasattr(request, 'query_params'):
            # DRF Request对象
            return request.query_params
        elif hasattr(request, 'GET'):
            # Django WSGIRequest对象
            return request.GET
        else:
            return {}

    def _apply_search(self, queryset, request, search_fields):
        """应用搜索功能"""
        query_params = self._get_query_params(request)
        search = query_params.get('search', '').strip()
        if not search or not search_fields:
            return queryset

        # 构建搜索查询
        search_queries = Q()
        for field in search_fields:
            search_queries |= Q(**{f"{field}__icontains": search})

        return queryset.filter(search_queries)

    def _apply_filters(self, queryset, request, filter_fields):
        """应用过滤功能 - 完全支持ViewSet的filterset_fields格式"""
        # 兼容四种格式：
        # 1. ViewSet列表格式: ['field_name', 'related__field']
        # 2. ViewSet简单字典: {'param_name': 'field_name'}
        # 3. ViewSet完整字典: {'field_name': ['exact', 'icontains']}
        # 4. 自定义配置格式: {'param_name': {'field': 'field_name', 'type': 'exact'}}

        # 如果是列表格式，转换为字典格式
        if isinstance(filter_fields, list):
            filter_fields = {field: field for field in filter_fields}

        for param_name, field_config in filter_fields.items():
            # 处理ViewSet完整字典格式：{'field_name': ['exact', 'icontains']}
            if isinstance(field_config, list):
                # ViewSet标准格式：字段支持多种查询类型
                field_name = param_name  # 参数名就是字段名
                queryset = self._apply_viewset_filter(queryset, request, field_name, field_config)
            elif isinstance(field_config, str):
                # ViewSet简单字典格式：{'param_name': 'field_name'}
                field_name = field_config
                query_params = self._get_query_params(request)
                param_value = query_params.get(param_name)
                if param_value is not None:
                    queryset = self._apply_simple_filter(queryset, field_name, param_value)
            elif isinstance(field_config, dict):
                # 自定义配置格式：{'param_name': {'field': 'field_name', 'type': 'exact'}}
                field_name = field_config.get('field')
                filter_type = field_config.get('type', 'exact')
                query_params = self._get_query_params(request)
                param_value = query_params.get(param_name)
                if param_value is not None:
                    queryset = self._apply_complex_filter(queryset, field_name, param_value, filter_type)

        return queryset

    def _apply_viewset_filter(self, queryset, request, field_name, lookup_types):
        """应用ViewSet标准的多查询类型过滤"""
        query_params = self._get_query_params(request)

        # 支持的查询类型映射
        for lookup_type in lookup_types:
            if lookup_type == 'exact':
                # 精确匹配：?field_name=value
                param_value = query_params.get(field_name)
                if param_value is not None:
                    queryset = self._apply_simple_filter(queryset, field_name, param_value)

            elif lookup_type == 'icontains':
                # 包含匹配：?field_name__icontains=value
                param_key = f"{field_name}__icontains"
                param_value = query_params.get(param_key)
                if param_value is not None:
                    queryset = queryset.filter(**{f"{field_name}__icontains": param_value})

            elif lookup_type == 'in':
                # 多值匹配：?field_name__in=value1,value2
                param_key = f"{field_name}__in"
                param_value = query_params.get(param_key)
                if param_value is not None:
                    values = [v.strip() for v in param_value.split(',') if v.strip()]
                    if values:
                        queryset = queryset.filter(**{f"{field_name}__in": values})

            elif lookup_type == 'gte':
                # 大于等于：?field_name__gte=value
                param_key = f"{field_name}__gte"
                param_value = query_params.get(param_key)
                if param_value is not None:
                    queryset = queryset.filter(**{f"{field_name}__gte": param_value})

            elif lookup_type == 'lte':
                # 小于等于：?field_name__lte=value
                param_key = f"{field_name}__lte"
                param_value = query_params.get(param_key)
                if param_value is not None:
                    queryset = queryset.filter(**{f"{field_name}__lte": param_value})

            elif lookup_type == 'isnull':
                # 是否为空：?field_name__isnull=true/false
                param_key = f"{field_name}__isnull"
                param_value = query_params.get(param_key)
                if param_value is not None:
                    is_null = param_value.lower() in ('true', '1', 'yes')
                    queryset = queryset.filter(**{f"{field_name}__isnull": is_null})

        return queryset

    def _apply_simple_filter(self, queryset, field_name, param_value):
        """应用简单过滤 - 智能类型转换"""
        try:
            # 智能类型转换
            if param_value.lower() in ('true', 'false'):
                # 布尔值
                param_value = param_value.lower() == 'true'
            elif param_value.isdigit():
                # 整数
                param_value = int(param_value)
            elif param_value.replace('.', '', 1).isdigit():
                # 浮点数
                param_value = float(param_value)

            return queryset.filter(**{field_name: param_value})
        except (ValueError, TypeError):
            return queryset

    def _apply_complex_filter(self, queryset, field_name, param_value, filter_type):
        """应用复杂过滤"""
        try:
            if filter_type == 'exact':
                return queryset.filter(**{field_name: param_value})
            elif filter_type == 'icontains':
                return queryset.filter(**{f"{field_name}__icontains": param_value})
            elif filter_type == 'in':
                # 支持逗号分隔的多值
                values = [v.strip() for v in param_value.split(',') if v.strip()]
                return queryset.filter(**{f"{field_name}__in": values})
            elif filter_type == 'boolean':
                # 布尔值转换
                bool_value = param_value.lower() in ('true', '1', 'yes', 'on')
                return queryset.filter(**{field_name: bool_value})
            elif filter_type == 'int':
                # 整数转换
                int_value = int(param_value)
                return queryset.filter(**{field_name: int_value})
            else:
                return queryset
        except (ValueError, TypeError):
            return queryset

    def _apply_ordering(self, queryset, request, ordering_fields, default_ordering):
        """应用排序功能"""
        query_params = self._get_query_params(request)
        ordering = query_params.get('ordering', '').strip()
        
        if ordering and ordering_fields:
            # 验证排序字段是否允许
            ordering_list = [o.strip() for o in ordering.split(',') if o.strip()]
            valid_orderings = []
            
            for order in ordering_list:
                # 处理降序标记
                field_name = order.lstrip('-')
                if field_name in ordering_fields:
                    valid_orderings.append(order)
            
            if valid_orderings:
                return queryset.order_by(*valid_orderings)
        
        # 应用默认排序
        if default_ordering:
            return queryset.order_by(*default_ordering)
        
        return queryset

    def get_action_config(self, action_name):
        """
        获取Action配置
        子类应该重写此方法来提供具体的配置
        
        Returns:
            dict: Action配置字典
        """
        action_configs = getattr(self, 'action_configs', {})
        return action_configs.get(action_name, {})

    def paginate_queryset_if_configured(self, queryset, action_name):
        """
        根据Action配置决定是否分页 - 完全模拟ViewSet的分页逻辑

        Args:
            queryset: 查询集
            action_name: Action名称

        Returns:
            分页后的数据或特殊标记
            - 如果use_pagination=True: 返回分页数据或None（与ViewSet的paginate_queryset一致）
            - 如果use_pagination=False: 返回特殊标记'NO_PAGINATION'表示强制不分页
        """
        action_config = self.get_action_config(action_name)
        use_pagination = action_config.get('use_pagination', False)

        if use_pagination:
            # 🔑 关键：完全模拟ViewSet的分页逻辑
            # 如果配置了use_pagination=True，则使用ViewSet的分页器
            if hasattr(self, 'paginate_queryset'):
                return self.paginate_queryset(queryset)  # 返回分页数据或None
            else:
                return None  # 没有分页器，返回None
        else:
            # 🔑 关键：如果配置了use_pagination=False，返回特殊标记表示强制不分页
            return 'NO_PAGINATION'
